home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
011-020
/
amok20
/
top
/
top.mod
< prev
next >
Wrap
Text File
|
1993-11-04
|
21KB
|
645 lines
(*---------------------------------------------------------------------------
:Program. Top
:Author. Uwe Meyer
:Address. Alex. v. Wacker P.4 5000 Köln 71
:Phone. 0221/704915
:Shortcut. [umk]
:Version. 1.0
:Date. 22-Apr-89
:Copyright. PD
:Language. Modula-II
:Translator. M2Amiga v3.2d
:Imports. IntuiStruct, Nicolas Benezan [bne]
:Contents. Baut ein neues Desktop auf
:Remark. Verwaltet zur Zeit max. 200 Files (keine dyn. ARRAY's)
:Usage. CLI:Top <keine Optionen> oder WORKBENCH: Icon doppelklicken
---------------------------------------------------------------------------*)
MODULE Top;
FROM SYSTEM IMPORT
ADR, ADDRESS, CAST, LONGSET;
FROM Arts IMPORT
TermProcedure, CurrentLevel, Assert;
FROM Conversions IMPORT
ValToStr;
FROM Dos IMPORT
Lock, UnLock, sharedLock, FileLockPtr, FileHandlePtr,
FileInfoBlock, FileInfoBlockPtr,
Examine, DeleteFile, CreateDir, Info, Rename, Execute, Delay,
Open, Close, Read, Write, oldFile, newFile;
FROM Exec IMPORT
Wait, GetMsg, ReplyMsg;
FROM Heap IMPORT
AllocMem, Deallocate;
FROM Intuition IMPORT
WindowPtr, SetWindowTitles, SizeWindow, GadgetPtr, GadgetFlags,
IDCMPFlagSet, IDCMPFlags, ModifyIDCMP, IntuiMessagePtr, DoubleClick,
WBenchToFront, ScreenToFront, MenuItemPtr, ItemAddress;
FROM IntuiStruct IMPORT
AllocProc, DeallocProc, MenuNull;
FROM Str IMPORT
Length, Concat, Copy;
FROM Topadd IMPORT
MyRequest, reqtext, REQLINES, REQGADS, GetName, CopyFile;
FROM Topimg IMPORT
DefineImages;
FROM Topinc IMPORT
Init, DefineMenus, ReadDir, SubPath, ParentPath,
MakeGadgets, Cleanup, CountSelected, FindSelected,
MAXDIR, PATHLEN, NAMELEN, DIR, PROP, XSPACE, YSPACE,
directory, pathname, entries, path, scr, window, win, act, prop,
gad, fgad, dgad, device, menustripptr, mylevel;
VAR dir : ARRAY [0..1],[0..MAXDIR] OF directory;
i : INTEGER; (* Zählvariable *)
gadact : INTEGER; (* Selekt. Gadget *)
msg : IntuiMessagePtr; (* Intuition - *)
msgclass : IDCMPFlagSet; (* Message - *)
msgcode : CARDINAL; (* System - *)
msgadr : GadgetPtr; (* Verwaltung *)
waitmask : LONGSET; (* WaitMaske *)
signal : LONGSET; (* WaitSignal *)
csec : LONGCARD; (* akt Zeit Sek. *)
cmic : LONGCARD; (* akt Zeit Mik. *)
ssec : LONGCARD; (* Start Zeit Sek. *)
smic : LONGCARD; (* Start Zeit Mik. *)
doubclick : BOOLEAN; (* Doppelklick ? *)
ok : BOOLEAN; (* Rückgabewert *)
check : INTEGER; (* Rückgabewert *)
reqt : ARRAY[0..REQLINES] OF reqtext;(* Requestertexte *)
reqg : ARRAY[0..REQGADS] OF reqtext; (* Reqgadgetstexte *)
warn : ARRAY [0..20] OF CHAR; (* Windowarntext *)
PROCEDURE NewDirectory;
CONST OLD = -1; (* alter Scrtitel *)
NODEV = -2; (* ReadDir Fehler *)
BEGIN
(*--------------------------------------------------------------------------)
Pfadnamen in Windowtitel setzen, Directory lesen, Prop-Position auf 0 stellen
und Directory in Form von Gadgets ausgeben. Fehlermeldung falls bei ReadDir
Pfadname nicht gefunden wurde
(--------------------------------------------------------------------------*)
SetWindowTitles (win[act], ADR ("WARTE! Lese Verzeichnis.."), OLD);
entries[act] := ReadDir (dir[act], path[act]);
prop[act].vertPot := 0;
IF entries[act] = NODEV THEN
entries[act] := -1;
warn := "Lesefehler auf ";
Concat (warn, path[act]);
SetWindowTitles (win[act], ADR (warn), OLD);
ELSE
MakeGadgets (act, dir[act], entries[act]);
SetWindowTitles (win[act], ADR (path[act]), OLD);
END;
END NewDirectory;
PROCEDURE ExecMenu (msgcode : CARDINAL) : BOOLEAN;
CONST DIR = 2;
OLD = -1;
VAR menunr : INTEGER; (* Nummer Menu *)
itemnr : INTEGER; (* Nummer Item *)
mitem : MenuItemPtr;
reqtmax : INTEGER; (* größte Reqtxtnr *)
src, des, hlp : ARRAY[0..30] OF CHAR; (* Source, Dest *)
filelockptr : FileLockPtr;
fileblockptr : FileInfoBlockPtr;
prot : LONGINT; (* ProtBits *)
i : INTEGER; (* Zähler *)
j : INTEGER; (* Zähler *)
BEGIN
(*--------------------------------------------------------------------------)
Das gewählte Menu inklusive Item aus der Message heraussuchen
(--------------------------------------------------------------------------*)
WHILE msgcode # MenuNull DO
mitem := ItemAddress (menustripptr, msgcode);
menunr := msgcode REM 32;
itemnr := msgcode / 32 REM 64;
msgcode := mitem^.nextSelect;
END;
IF menunr = 0 THEN
IF itemnr = 0 THEN
(*--------------------------------------------------------------------------)
Es wurde ABOUT angewählt
(--------------------------------------------------------------------------*)
reqt[0] := "T O P Version 1.0";
reqt[1] := " von Uwe Meyer";
reqt[2] := " ";
reqt[3] := " Mitglied der ";
reqt[4] := " Soft-Ware-Army";
reqg[0] := " PD";
reqg[1] := " PD";
check := MyRequest (scr, ADR ("Programm-Info"), 4, reqt, 50, 1, reqg);
ELSE
(*--------------------------------------------------------------------------)
QUIT bringt eine MyRequest Nachricht, ExecMenu gibt daraufhin FALSE zurück
(--------------------------------------------------------------------------*)
reqt[0] := "Wirklich Schluß ?"; (* Quit *)
reqg[0] := " Ja";
reqg[1] := "Nein";
check := MyRequest (scr, ADR ("Quit-Request"), 0, reqt, 40, 1, reqg);
IF check = 0 THEN
RETURN (FALSE);
END;
END;
ELSIF menunr = 1 THEN
i := CountSelected (fgad[act]);
(*--------------------------------------------------------------------------)
DateiInfo ausgeben (mindestens 1 ausgewählt), Speicher für FileInfo anfordern
(--------------------------------------------------------------------------*)
IF (itemnr = 0) AND (i # 0) THEN (* Info *)
AllocMem (fileblockptr, SIZE (FileInfoBlock), FALSE);
i := -1;
REPEAT
INC (i);
i := FindSelected (i, fgad[act]);
IF (i # -1) THEN
Copy (src, path[act]);
SubPath (src, dir[act, i].name);
(*--------------------------------------------------------------------------)
FileInfoBlockPtr mit Lock und Examine laden
(--------------------------------------------------------------------------*)
filelockptr := Lock (ADR (src), sharedLock);
ok := Examine (filelockptr, fileblockptr);
reqt[0] := "Name : ";
Concat (reqt[0], dir[act, i].name);
reqt[1] := "Typ : ";
(*--------------------------------------------------------------------------)
Falls Datei ein SubDir ist nur Dateinamen und ProtectionBits ausgeben
(--------------------------------------------------------------------------*)
IF dir[act, i].type = DIR THEN
Concat (reqt[1], "DIR");
reqtmax := 2;
ELSE
Concat (reqt[1], "DATEI");
reqtmax := 4;
END;
(*--------------------------------------------------------------------------)
Auswertung der Protection Bit Maske
(--------------------------------------------------------------------------*)
reqt[2] := "ProtBits : ";
src := "DEWRASPH";
prot := CAST (LONGINT, fileblockptr^.protection);
FOR j := 0 TO 3 DO (* Bits 0..3 *)
IF prot MOD 2 # 0 THEN (* sind aktiv = 1 *)
src[j] := "-";
END;
prot := prot DIV 2;
END;
FOR j := 4 TO 7 DO (* Bits 4..7 *)
IF prot MOD 2 = 0 THEN (* sind aktiv = 0 *)
src[j] := "-";
END;
prot := prot DIV 2;
END;
Concat (reqt[2], src);
(*--------------------------------------------------------------------------)
Byte und Blocklänge in Requestertext eintragen und Requester aufrufen
(--------------------------------------------------------------------------*)
reqt[3] := "Bytes : ";
ValToStr (fileblockptr^.size, FALSE, src, 10, 6, " ", ok);
Concat (reqt[3], src);
reqt[4] := "Blöcke : ";
ValToStr (fileblockptr^.numBlocks, FALSE, src, 10, 6, " ", ok);
Concat (reqt[4], src);
reqg[0] := "Weiter";
reqg[1] := " Stop";
check := MyRequest (scr, ADR ("Info-Request"), reqtmax, reqt, 54,
1, reqg);
IF check = 1 THEN
i := -1;
END;
UnLock (filelockptr);
END;
UNTIL i = -1;
Deallocate (fileblockptr);
(*--------------------------------------------------------------------------)
Makedir verändert den Fenstertitel, holt sich per Stringgadget einen neuen
Namen (ÜbergabeString scr = "") und erzeugt mit CreateDir ein neues SubDir
(--------------------------------------------------------------------------*)
ELSIF itemnr = 1 THEN (* MakeDir *)
src[0] := CHAR (0);
SetWindowTitles (win[act], ADR ("Tippe neuen Dirnamen ein!"), OLD);
GetName (win[act], src);
Copy (des, path[act]);
SubPath (des, src);
filelockptr := CreateDir (ADR (des));
UnLock (filelockptr);
NewDirectory;
(*--------------------------------------------------------------------------)
Rename arbeitet ähnlich MakeDir, nur wird der alte Name an GetName übergeben
(--------------------------------------------------------------------------*)
ELSIF (itemnr = 2) AND (i # 0) THEN (* Rename *)
i := -1;
REPEAT
INC (i);
i := FindSelected (i, fgad[act]);
IF (i # -1) THEN
SetWindowTitles (win[act], ADR ("Tippe den neuen Namen ein!"), OLD);
Copy (hlp, dir[act, i].name);
GetName (win[act], hlp);
Copy (src, path[act]);
SubPath (src, dir[act, i].name);
Copy (des, path[act]);
SubPath (des, hlp);
ok := Rename (ADR (src), ADR (des));
IF ok THEN
Copy (dir[act, i].name, hlp);
END;
END;
UNTIL i = -1;
MakeGadgets (act, dir[act], entries[act]);
(*--------------------------------------------------------------------------)
Copy benutzt eine eigene Kopierroutine aus Topadd und kopiert alle ange-
wählten Dateien. Nur das Ziellaufwerk wird mit NewDirectory aufgerufen
(--------------------------------------------------------------------------*)
ELSIF (itemnr = 3) AND (i # 0) THEN (* Copy *)
reqt[0] := "Kopiere ";
ValToStr (i, FALSE, src, 10, 3, " ", ok);
Concat (reqt[0], src);
Concat (reqt[0], " Datei(en)");
reqt[1] := "VON ";
Concat (reqt[1], path[act]);
reqt[2] := "NACH ";
Concat (reqt[2], path[1 - act]);
reqg[0] := " Ja";
reqg[1] := "Nein";
check := MyRequest (scr, ADR ("Kopier-Request"), 2, reqt, 40, 1, reqg);
IF check = 0 THEN
i := -1;
REPEAT
INC (i);
i := FindSelected (i, fgad[act]);
IF (i # -1) AND (dir[act, i].type # DIR) THEN
warn := "Kopiere ";
Concat (warn, dir[act, i].name);
SetWindowTitles (win[act], ADR (warn), OLD);
Copy (src, path[act]);
Copy (des, path[1 - act]);
SubPath (src, dir[act, i].name);
SubPath (des, dir[act, i].name);
IF NOT CopyFile (src, des) THEN
warn := "Kopierfehler bei ";
Concat (warn, src);
SetWindowTitles (win[act], ADR (warn), OLD);
Delay (100);
i := -1;
END;
END;
UNTIL i = -1;
SetWindowTitles (win[act], ADR (path[act]), OLD);
act := 1 - act;
NewDirectory;
act := 1 - act;
END;
ELSIF (itemnr = 4) AND (i # 0) THEN
(*--------------------------------------------------------------------------)
Delete löscht Files; aber nur leere Directories
(--------------------------------------------------------------------------*)
reqt[0] := "Lösche "; (* Delete *)
ValToStr (i, FALSE, src, 10, 3, " ", ok);
Concat (reqt[0], src);
Concat (reqt[0], " Datei(en)");
reqt[1] := "VON ";
Concat (reqt[1], path[act]);
reqg[0] := " Ja";
reqg[1] := "Nein";
check := MyRequest (scr, ADR ("Lösch-Request"), 1, reqt, 40, 1, reqg);
IF check = 0 THEN
i := -1;
REPEAT
INC (i);
i := FindSelected (i, fgad[act]);
IF i # -1 THEN
warn := "Lösche ";
Concat (warn, dir[act, i].name);
SetWindowTitles (win[act], ADR (warn), OLD);
Copy (src, path[act]);
SubPath (src, dir[act, i].name);
IF NOT DeleteFile (ADR (src)) THEN
warn := "Löschfehler bei ";
Concat (warn, src);
SetWindowTitles (win[act], ADR (warn), OLD);
END;
END;
UNTIL i = -1;
NewDirectory;
END;
END;
END;
RETURN (TRUE);
END ExecMenu;
PROCEDURE KlickItem;
VAR port1[0BFE001H] : SET OF(s0,s1,s2,s3,s4,s5,lmb);(* linke Maustaste *)
fh : FileHandlePtr; (* Datei Handle *)
par : FileHandlePtr; (* PRT: Handle *)
con : FileHandlePtr; (* CON-Win. Handle *)
title : ARRAY [0..PATHLEN] OF CHAR; (* CON-Win. Titel *)
count : LONGINT; (* bearbeit. Bytes *)
buf : ARRAY [0..80] OF CHAR; (* Filepuffer *)
sel : INTEGER; (* selekt. Gadgets *)
exename : ARRAY [0..200] OF CHAR; (* Startname&Parms *)
ok : BOOLEAN; (* Status Flag *)
BEGIN
(*--------------------------------------------------------------------------)
Start- und aktuelle Messagezeiten auf Doppelklick testen. Zeiten tauschen
(--------------------------------------------------------------------------*)
doubclick := DoubleClick (ssec, smic, csec, cmic);
ssec := csec;
smic := cmic;
(*--------------------------------------------------------------------------)
Handelte es sich um einen Doppelklick? Bei DIR's Pfad ändern und lesen
(--------------------------------------------------------------------------*)
IF doubclick THEN
SubPath (path[act], dir[act, gadact].name);
IF (dir[act,gadact].type = DIR) THEN
NewDirectory;
ELSE
(*--------------------------------------------------------------------------)
Für alle anderen Dateien eigenes CON-Fenster zur Ausgabe eröffnen
(--------------------------------------------------------------------------*)
title := "CON:0/11/640/245/";
Concat (title, path[act]);
con := Open (ADR (title), oldFile);
(*--------------------------------------------------------------------------)
Vier Bytes der Datei lesen und auf Ausführbarkeit prüfen (00 00 03 F3);
(--------------------------------------------------------------------------*)
fh := Open (ADR (path[act]), oldFile);
IF fh # NIL THEN
count := Read (fh, ADR (buf[0]), 4);
Close (fh);
IF (buf[0] = CHAR (0)) AND (buf[1] = CHAR (0))
AND (buf[2] = CHAR(3)) AND (buf[3] = CHAR (243)) THEN
(*--------------------------------------------------------------------------)
Parameter für ausführbare Datei aus anderem Fenster holen und EXECUTE'n
(--------------------------------------------------------------------------*)
Copy (exename, path[act]);
IF CountSelected (fgad[1 - act]) = 1 THEN;
act := 1 - act;
sel := 0;
sel := FindSelected (0, fgad[act]);
Concat (exename, " ");
Concat (exename, path[act]);
IF path[act, Length (path[act]) - 1] # ":" THEN
Concat (exename, "/");
END;
Concat (exename, dir[act, sel].name);
act := 1 - act;
END;
ok := WBenchToFront ();
check := Execute (ADR (exename), NIL, con);
ELSE
(*--------------------------------------------------------------------------)
Nicht ausführbare Datei auf Monitor oder Drucker ausgeben
(Bis durch Druck auf die linke Maustaste abgebrochen wird)
(--------------------------------------------------------------------------*)
reqt[0] := " Ausgabe der Datei";
reqt[1] := "auf welches Ausgabegerät?";
reqg[0] := "Monitor";
reqg[1] := "Drucker";
reqg[2] := "Abbruch";
check := MyRequest (scr, ADR ("Ausgabe-Request"), 1, reqt, 62, 2, reqg);
IF check # 2 THEN
fh := Open (ADR (path[act]), oldFile);
IF fh # NIL THEN
IF check = 1 THEN
par := Open (ADR ("PRT:"), newFile);
END;
ok := WBenchToFront ();
REPEAT
count := Read (fh, ADR (buf[0]), 80);
count := Write (con, ADR (buf[0]), count);
IF check = 1 THEN
count := Write (par, ADR (buf[0]), count);
END;
UNTIL (NOT (lmb IN port1)) OR (count # 80);
IF check = 1 THEN
buf[0] := CHAR (13);
count := Write (par, ADR (buf[0]), 1);
Close (par);
END;
Close (fh);
END;
END;
END;
END;
(*--------------------------------------------------------------------------)
Pfad zurücksetzen, Gadgets erneuern und auf linke Maustaste warten
(--------------------------------------------------------------------------*)
ParentPath (path[act]);
MakeGadgets (act, dir[act], entries[act]);
WHILE lmb IN port1 DO
Delay (5);
END;
ScreenToFront (scr);
Close (con);
END;
END;
END KlickItem;
PROCEDURE SizeIt;
CONST TITLESPACE = 15; (* Höhe Tit.leiste *)
WINSPACE = 18; (* Höhe Win.rahmen *)
INFOSPACE = 13; (* Höhe Infozeile *)
PROPWIDTH = 16; (* Propgad.breite *)
VAR width : INTEGER; (* Neue Win.breite *)
height : INTEGER; (* Neue Win.höhe *)
idcmp : IDCMPFlagSet; (* IDCMP Retter *)
BEGIN
(*--------------------------------------------------------------------------)
Da SizeWindow eine Message schickt, wird der IDCMP ausgeschaltet
(--------------------------------------------------------------------------*)
idcmp := win[i]^.idcmpFlags;
ModifyIDCMP (win[i], IDCMPFlagSet {});
(*--------------------------------------------------------------------------)
Überprüfung der neuen und alten Window- und Screengrößen
(--------------------------------------------------------------------------*)
width := ((win[i]^.width - PROPWIDTH) / XSPACE) * XSPACE + PROPWIDTH;
height := ((win[i]^.height - TITLESPACE) / YSPACE) * YSPACE
+ TITLESPACE + INFOSPACE;
IF width > scr^.width - win[i]^.leftEdge THEN
width := scr^.width - win[i]^.leftEdge;
END;
IF height > scr^.height - win[i]^.topEdge THEN
height := scr^.height - win[i]^.topEdge;
END;
IF width < XSPACE + PROPWIDTH THEN
width := XSPACE + PROPWIDTH;
END;
IF height < YSPACE + TITLESPACE THEN
height := YSPACE + TITLESPACE + INFOSPACE;
END;
SizeWindow (win[i], width - win[i]^.width, height - win[i]^.height);
Delay (10);
gad[i].height := height - WINSPACE;
prop[act].vertPot := 0;
MakeGadgets (i, dir[i], entries[i]);
ModifyIDCMP (win[i], idcmp);
END SizeIt;
PROCEDURE ChangeDevice;
CONST OLD = -1;
BEGIN
(*--------------------------------------------------------------------------)
War es Doppelklick? Wenn ja wird das Directory des neuen Devices sofort
eingelesen, sonst wird nur der Windowtitle neu gesetzt
(--------------------------------------------------------------------------*)
msgadr := msg^.iAddress;
gadact := msgadr^.gadgetID;
Delay (10);
msg := GetMsg (window^.userPort);
msgclass := msg^.class;
Copy (path[act], device[gadact]);
IF msg # NIL THEN
msgadr := msg^.iAddress;
gadact := msgadr^.gadgetID;
ReplyMsg (msg);
NewDirectory;
ELSE
SetWindowTitles (win[act], ADR (path[act]), OLD);
END;
END ChangeDevice;
(*** Hauptprogramm ***)
BEGIN
mylevel := CurrentLevel ();
TermProcedure (Cleanup);
(*--------------------------------------------------------------------------)
Speicherreservierungsprozeduren für Intuistruct angeben
(--------------------------------------------------------------------------*)
AllocProc := AllocMem;
DeallocProc := Deallocate;
(*--------------------------------------------------------------------------)
Image und Menustrukturen aufbauen;
Screen, Fenster und sonstige Startwerte vorbereiten
(--------------------------------------------------------------------------*)
DefineImages;
DefineMenus;
Init;
(*--------------------------------------------------------------------------)
Auf Message von einem der 3 Fenster warten
(--------------------------------------------------------------------------*)
LOOP
waitmask := LONGSET {window^.userPort^.sigBit};
waitmask := waitmask + LONGSET {win[0]^.userPort^.sigBit};
waitmask := waitmask + LONGSET {win[1]^.userPort^.sigBit};
signal := Wait (waitmask);
msg := GetMsg (window^.userPort);
IF msg # NIL THEN
ReplyMsg (msg);
ChangeDevice;
END;
FOR i := 0 TO 1 DO
msg := GetMsg (win[i]^.userPort);
WHILE msg # NIL DO
msgclass := msg^.class;
csec := msg^.seconds;
cmic := msg^.micros;
ReplyMsg (msg);
IF activeWindow IN msgclass THEN
act := i;
ELSIF closeWindow IN msgclass THEN
ParentPath (path[act]);
NewDirectory;
ELSIF gadgetUp IN msgclass THEN
msgadr := msg^.iAddress;
gadact := msgadr^.gadgetID;
IF gadact = PROP THEN
MakeGadgets (act, dir[act], entries[act]);
ELSE
KlickItem;
END;
ELSIF newSize IN msgclass THEN
SizeIt;
ELSIF menuPick IN msgclass THEN
msgcode := msg^.code;
IF NOT ExecMenu (msgcode) THEN
EXIT;
END;
END;
msg := GetMsg (win[i]^.userPort);
END;
END;
END;
END Top.